/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.controller.admin;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.messages.request.SimpleRequestMessage;
import cn.easyplatform.messages.vos.admin.ServiceVo;
import cn.easyplatform.spi.service.AdminService;
import cn.easyplatform.type.IResponseMessage;
import cn.easyplatform.web.contexts.Contexts;
import cn.easyplatform.web.dialog.MessageBox;
import cn.easyplatform.web.listener.MessageEventListener;
import cn.easyplatform.web.log.LogManager;
import cn.easyplatform.web.message.entity.Message;
import cn.easyplatform.web.service.ServiceLocator;
import org.zkoss.util.media.AMedia;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zkmax.zul.Filedownload;
import org.zkoss.zul.*;

/**
 * @Author: <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @Description:
 * @Since: 2.0.0 <br/>
 * @Date: Created in 2019/11/7 15:37
 * @Modified By:
 */
public class RealController extends SelectorComposer<Component> {

    @Wire("combobox#type")
    private Combobox type;

    @Wire("html#console")
    private Html console;

    @Wire("combobox#level")
    private Combobox level;

    @Wire("button#start")
    private Button start;

    @Wire("caption#caption")
    private Caption caption;

    private EventListener<Event> consoleSubscriber;

    private String targetId;

    @Override
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        level.setSelectedIndex(2);
        final EventListener<?> el = event -> {
            if (consoleSubscriber != null) {
                if (type == null || type.getSelectedIndex() == 0)
                    ServiceLocator.lookup(AdminService.class).console(new SimpleRequestMessage(new Object[]{targetId, false}));
                else
                    LogManager.stop();
                Contexts.unsubscribe(Message.LOG, consoleSubscriber);
                consoleSubscriber = null;
            }
        };
        if (comp instanceof Window) {
            ServiceVo vo = (ServiceVo) Executions.getCurrent().getArg().get("s");
            targetId = vo.getId();
            caption.setLabel(Labels.getLabel("admin.event.uesr") + " : " + vo.getId() + " (" + vo.getName() + ")");
            caption.setIconSclass("z-icon-cog z-icon-spin");
            comp.addEventListener(Events.ON_CLOSE, el);
            onStart(new Event(Events.ON_CLICK, start));
        } else {
            type.setSelectedIndex(0);
            targetId = "";
            Tabpanel c = (Tabpanel) comp.getParent().getParent();
            c.getLinkedTab().addEventListener(Events.ON_CLOSE, el);
        }
    }

    @Listen("onClick = #start")
    public void onStart(Event evt) {
        Button btn = (Button) evt.getTarget();
        boolean enabled = btn.getIconSclass().equals("z-icon-play") ? true
                : false;
        if (!enabled) {
            btn.setIconSclass("z-icon-play");
            btn.setLabel(Labels.getLabel("debug.log.start"));
        } else {
            btn.setIconSclass("z-icon-stop");
            btn.setLabel(Labels.getLabel("debug.log.stop"));
        }
        if (type != null)
            type.setDisabled(enabled);
        if (type == null || type.getSelectedIndex() == 0) {
            IResponseMessage<?> resp = ServiceLocator.lookup(AdminService.class).console(new SimpleRequestMessage(new Object[]{targetId, enabled}));
            if (resp.isSuccess()) {
                if (enabled) {
                    consoleSubscriber = new MessageEventListener(console);
                    Contexts.subscribe(Message.LOG, consoleSubscriber);
                } else {
                    Contexts.unsubscribe(Message.LOG, consoleSubscriber);
                    consoleSubscriber = null;
                }
            } else
                MessageBox.showMessage(resp);
        } else {
            if (enabled) {
                consoleSubscriber = new MessageEventListener(console);
                Contexts.subscribe(Message.LOG, consoleSubscriber);
                LogManager.startApiConsole();
            } else {
                LogManager.stop();
                Contexts.unsubscribe(Message.LOG, consoleSubscriber);
                consoleSubscriber = null;
            }
        }

    }

    @Listen("onSelect = #level")
    public void onSetLevel() {
        if (consoleSubscriber == null) {
            MessageBox.showMessage(Labels.getLabel("message.dialog.title.info"), Labels.getLabel("admin.log.set.level"));
        } else {
            console.setContent("$$clear$$");
            ServiceLocator.lookup(AdminService.class).console(new SimpleRequestMessage(new Object[]{targetId, level.getSelectedItem().getLabel()}));
        }
    }

    @Listen("onClick = #clear")
    public void onClear() {
        console.setContent("$$clear$$");
    }

    @Listen("onClick = #export")
    public void onExport() {
        if (!Strings.isBlank(console.getContent())) {
            StringBuilder sb = new StringBuilder();
            sb.append("<head>")
                    .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />")
                    .append("</head>").append(console.getContent());
            AMedia media = new AMedia("apps.html", "html", "text/html",
                    sb.toString());
            sb = null;
            Filedownload.save(media);
        }
    }
}
